package pfc.ventanas;

import java.util.LinkedList;
import java.util.Vector;

//Imports Java Swing
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


import pfc.Aplicacion;
import pfc.Interfaz;
import pfc.ventanas.Ventana;
import pfc.ventanas.WindowAdapterPrincipal;
import pfc.mensaje.*;
import pfc.Usuario;
import pfc.Constantes;


/**
 *
 * Implementa la ventana principal.
 * @author Gabriel Reus Rodríguez
 * @version 1.0, 19/11/2010
*/


public class VentanaPrincipal extends Ventana implements ActionListener
{
	private final static String NOMBRE_TEXTAREA_GENERAL="textArea general";
	private final static String NOMBRE_TEXTFIELD_ENTRADA="textfield entrada";
	private final static String ACCION_BOTON_ENVIAR="boton enviar";
	private final static String ACCION_BOTON_NUEVA_CONVERSACION="boton conversacion";

	private boolean conexion=false;

	private JTextArea jtAreaOutput=null;
	private JTextField inputTexto=null;
	private JScrollPane scroll=null;
	private JScrollPane scroll_lista=null;
	private JList lista_usuarios=null;

	/**
	 * Constructor de la ventana principal
	*/
	public VentanaPrincipal()
	{
		super(null);
		createGui();
	}

	public VentanaPrincipal(Aplicacion a)
	{
		super(a);
		createGui();
		// trap window close and do something in an anonymous inner class
		frame.addWindowListener(new WindowAdapterPrincipal(a));
	}

	/**
	 * Crea la interfaz
	*/
	private void createGui()
	{

		JFrame.setDefaultLookAndFeelDecorated(true);
		// Create and set up the window.
		frame = new JFrame("Chat-EasyPastry");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setJMenuBar(this.createJMenuBar());
		frame.setContentPane(this.createContentPane());
		frame.setSize(Constantes.TAMANO_VENTANA_PRINCIPAL_X, Constantes.TAMANO_VENTANA_PRINCIPAL_Y);
		frame.setVisible(true);
	}

	/**
	*Crea el contenido de la ventana principal
	*/
	private Container createContentPane() {
		// Create the content-pane-to-be.
		JPanel jplContentPane = new JPanel();
		jplContentPane.setLayout(new GridBagLayout());
		jplContentPane.setOpaque(true);

	        GridBagConstraints gBC = new GridBagConstraints();

		JPanel panelListaUsuarios = new JPanel();
		panelListaUsuarios.setLayout(new GridBagLayout());

		Vector<String> users= new Vector<String>();
		users.add("No hay usuarios conectados.");

		lista_usuarios= new JList(users);
		lista_usuarios.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
		gBC.gridwidth = GridBagConstraints.REMAINDER;
		panelListaUsuarios.add(lista_usuarios, gBC);		
		JButton boton= new JButton("Crear charla");
		boton.setActionCommand(ACCION_BOTON_NUEVA_CONVERSACION);
		boton.addActionListener(this);		
		panelListaUsuarios.add(boton,gBC);
		gBC.gridwidth = GridBagConstraints.RELATIVE;
		jplContentPane.add(panelListaUsuarios, gBC);
		

		JPanel general = new JPanel();
		general.setLayout(new GridBagLayout());

		jtAreaOutput = new JTextArea(20, 35);
		jtAreaOutput.setName(NOMBRE_TEXTAREA_GENERAL);
		jtAreaOutput.setEditable(false);
		jtAreaOutput.setLineWrap(true);
		jtAreaOutput.setRows(20);

		scroll = new JScrollPane(jtAreaOutput);
		scroll.setName("Scroll_general");
		gBC.gridwidth = GridBagConstraints.REMAINDER;
		general.add(scroll,gBC);

		inputTexto= new JTextField(20);
		inputTexto.setName(NOMBRE_TEXTFIELD_ENTRADA);
		//http://download.oracle.com/javase/1.5.0/docs/api/java/awt/GridBagLayout.html
		gBC.gridwidth = GridBagConstraints.RELATIVE;
		general.add(inputTexto,gBC);

		//Agrego un boton		
		JButton button = new JButton("Envíar");
		button.setActionCommand(ACCION_BOTON_ENVIAR);
		button.addActionListener(this);		
		gBC.gridwidth = GridBagConstraints.RELATIVE;

		general.add(button,gBC);

		jplContentPane.add(general, gBC);
		return jplContentPane;
	}

	/**
	 * Crea la barra de menu
	*/
	private JMenuBar createJMenuBar() {

		JMenuBar mainMenuBar;
		JMenu menuArchivo, menuAyuda;//, submenu;
		//Creo la barra de menus.
		mainMenuBar = new JMenuBar();
		//Creo la primera pestaña.
		menuArchivo = new JMenu("Opciones");
//		menuArchivo.setMnemonic(KeyEvent.VK_M);
		menuAyuda= new JMenu("Ayuda");
//		menuArchivo.setMnemonic(KeyEvent.VK_M);
		mainMenuBar.add(menuArchivo);
		mainMenuBar.add(menuAyuda);
		//Creo los items del menu Archivo.
		//Nueva Ventana
		JMenuItem NuevaVentanaMenuItem = new JMenuItem("Nueva conexión",
				KeyEvent.VK_T);
		NuevaVentanaMenuItem.setActionCommand("nueva_conexion");
		// can be done either way for assigning shortcuts
		// menuItem.setMnemonic(KeyEvent.VK_T);
		// Accelerators, offer keyboard shortcuts to bypass navigating the menu
		// hierarchy.
		NuevaVentanaMenuItem.setAccelerator(KeyStroke.getKeyStroke(
				KeyEvent.VK_1, ActionEvent.ALT_MASK));
		NuevaVentanaMenuItem.addActionListener(this);
		menuArchivo.add(NuevaVentanaMenuItem);

		//Desconectar
		JMenuItem desconectar = new JMenuItem("Desconectar",
				KeyEvent.VK_T);
		desconectar.setActionCommand("desconexion");
		// can be done either way for assigning shortcuts
		// menuItem.setMnemonic(KeyEvent.VK_T);
		// Accelerators, offer keyboard shortcuts to bypass navigating the menu
		// hierarchy.
		/*desconectar.setAccelerator(KeyStroke.getKeyStroke(
				KeyEvent.VK_1, ActionEvent.ALT_MASK));*/
		desconectar.setEnabled(false);
		desconectar.addActionListener(this);
		menuArchivo.add(desconectar);

		//Salir
		JMenuItem SalirMenuItem = new JMenuItem("Salir",
				KeyEvent.VK_T);
		SalirMenuItem.setActionCommand("salir");
		// can be done either way for assigning shortcuts
		// menuItem.setMnemonic(KeyEvent.VK_T);
		// Accelerators, offer keyboard shortcuts to bypass navigating the menu
		// hierarchy.

		SalirMenuItem.addActionListener(this);
		menuArchivo.add(SalirMenuItem);

		//Menu de ayuda.
		JMenuItem sobre = new JMenuItem("Sobre");
		sobre.setActionCommand("sobre");
		sobre.addActionListener(this);
		menuAyuda.add(sobre);

		return mainMenuBar;		
	
	}

	/**
	* Crea la ventana para introducir los datos de conexión.
	*/
	private void creaDialogo_Conexion()
	{

		dialog= new JDialog();

		dialog.setTitle("Datos de conexión");

		Container contentPane = dialog.getContentPane();
		contentPane.setLayout(new GridBagLayout());
	        GridBagConstraints gBC = new GridBagConstraints();

		JLabel jlabel= new JLabel("Introduce los siguientes datos para conectarte al anillo:");
		gBC.gridwidth = GridBagConstraints.REMAINDER;
		contentPane.add(jlabel, gBC);

		gBC.gridwidth = GridBagConstraints.RELATIVE;
		JLabel jlabel2= new JLabel("Grupo: ");
		contentPane.add(jlabel2, gBC);

		JTextField jTextGrupo= new JTextField(20);
		gBC.gridwidth = GridBagConstraints.REMAINDER;
		jTextGrupo.setName("Grupo");
		contentPane.add(jTextGrupo, gBC);

		JLabel jlabel4= new JLabel("Contexto: ");
		gBC.gridwidth = GridBagConstraints.RELATIVE;
		contentPane.add(jlabel4, gBC);

		JTextField jTextContexto= new JTextField(20);
		gBC.gridwidth = GridBagConstraints.REMAINDER;
		jTextContexto.setName("Contexto");
		contentPane.add(jTextContexto, gBC);

		JLabel jlabel6= new JLabel("Nick: ");
		gBC.gridwidth = GridBagConstraints.RELATIVE;
		contentPane.add(jlabel6, gBC);

		JTextField jTextNick= new JTextField(20);
		gBC.gridwidth = GridBagConstraints.REMAINDER;
		jTextNick.setName("Nick");
		contentPane.add(jTextNick, gBC);

		JButton boton= new JButton("Conectar");
		boton.addActionListener(this);
		boton.setActionCommand("conexion");
		gBC.gridheight = GridBagConstraints.REMAINDER;
		contentPane.add(boton, gBC);

		dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		dialog.setSize(new Dimension(500, 150));
		dialog.setVisible(true);
	}

	/**
	* Crea la ventana con información de la aplicación.
	*/
	private void creaDialogo_Sobre()
	{
		JFrame credi;
		credi=new JFrame();
		dialog = new JDialog(credi, "", true);

		dialog.setTitle("Creditos");
		
		JTextArea label = new JTextArea("Programa de mensajería instantania descentralizado usando EasyPastry\n"+
					 "\t Autor: Gabriel Reus Rodríguez, gabriel.reus@gmail.com");
		label.setEditable(false);//No editable.
		label.setOpaque(false); //Transparente
		dialog.setLocationRelativeTo(frame); // Centro la posicion. queda pendiente de revision

		Container contentPane = dialog.getContentPane();
		contentPane.add(label, BorderLayout.CENTER);

		dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		dialog.setSize(new Dimension(500, 70));
		dialog.setVisible(true);
	}


	/**
	 * Escucha los eventos.
	*/
	public void actionPerformed(ActionEvent e) {

		//Salir
		if( 	("JMenuItem".equalsIgnoreCase(getClassName(e.getSource()))) && 
			("salir".equalsIgnoreCase(e.getActionCommand())) 
		  )
		{
			aplicacion.salir();
		}
		//Pantalla de la Nueva conexión
		if( 	("JMenuItem".equalsIgnoreCase(getClassName(e.getSource()))) && 
			("nueva_conexion".equalsIgnoreCase(e.getActionCommand())) 
		  )
		{
			creaDialogo_Conexion();
		}
		//Conexion al anillo
		if( 	("JButton".equalsIgnoreCase(getClassName(e.getSource()))) && 
			("conexion".equalsIgnoreCase(e.getActionCommand())) 
		  )
		{
			//creaDialogo_Conexion();
			//Interfaz.addVentana();
			String grupo="";
			String contexto="";
			String nick="";


			try
			{
				JTextField jGrupo=(JTextField)obtenComponente("Grupo",dialog.getContentPane());
				JTextField jContexto=(JTextField)obtenComponente("Contexto",dialog.getContentPane());
				JTextField jNick=(JTextField)obtenComponente("Nick",dialog.getContentPane());

				grupo=jGrupo.getText();
				contexto=jContexto.getText();
				nick=jNick.getText();
				//Obtengo los  parametros.
				aplicacion.conectar(grupo,contexto,nick);
				//this.conexion=true;
				cambiaEstadoConexion();
				escribeGeneral(nick+", has conectado al anillo: "+grupo);
			}
			catch(Exception ex)
			{
				notificaExcepcion(ex);
			}
			dialog.dispose();
			
		}
		//Desconexion
		if( 	("JMenuItem".equalsIgnoreCase(getClassName(e.getSource()))) && 
			("desconexion".equalsIgnoreCase(e.getActionCommand())) 
		  )
		{
			cambiaEstadoConexion();
			try
			{
				aplicacion.desconectar();
				escribeGeneral("Has desconectado del anillo");
			}
			catch(Exception ex)
			{
				notificaExcepcion(ex);
			}
		}
		//Enviar mensaje a todos
		if( 	("JButton".equalsIgnoreCase(getClassName(e.getSource()))) && 
			(this.ACCION_BOTON_ENVIAR.equalsIgnoreCase(e.getActionCommand())) 
		  )
		{
			//No escribo nada porque recibiré el propio multicast
			try
			{
				aplicacion.enviarMensajeMultiCast(new Texto(inputTexto.getText(),this.aplicacion.getCliente().getGrupo(),null,aplicacion.getUsuario()));
				escribeEntrada("");
			}
			catch(Exception ex)
			{
				notificaExcepcion(ex);
			}
		}

		//Creo una nueva Conversacion
		if( 	("JButton".equalsIgnoreCase(getClassName(e.getSource()))) && 
			(this.ACCION_BOTON_NUEVA_CONVERSACION.equalsIgnoreCase(e.getActionCommand())) 
		  )
		{

			LinkedList<String> participantes= new LinkedList<String>();
			try
			{
				Object[] sel = lista_usuarios.getSelectedValues();
				for (int i=0;i<sel.length;i++)
				{
					participantes.add((String)sel[i]);
				}
				aplicacion.nuevaConversacion(participantes);
			}
			catch(Exception ex)
			{
				notificaExcepcion(ex);
			}

		}



		//Sobre
		if( 	("JMenuItem".equalsIgnoreCase(getClassName(e.getSource()))) && 
			("sobre".equalsIgnoreCase(e.getActionCommand())) 
		  )
		{
			creaDialogo_Sobre();
			//Interfaz.addVentana();
		}
	}

	/**
	 * Si estamos conectados habilita el menu de conexión y deshabilita el de desconexión y viceversa.
	*/
	private void cambiaEstadoConexion()
	{
		JMenuBar menubar= frame.getJMenuBar();
		JMenu jmenu=menubar.getMenu(0);
		//Obtengo los items.
		JMenuItem menuConexion= jmenu.getItem(0);
		JMenuItem menuDesconexion= jmenu.getItem(1);
		//Si estoy conectado...
		if((this.aplicacion).estaConectado())
		{
			menuConexion.setEnabled(false);
			menuDesconexion.setEnabled(true);
		}
		//Si estoy desconectado...
		else
		{
			menuConexion.setEnabled(true);
			menuDesconexion.setEnabled(false);
		}
	}
	/**
	*Escribe el texto que le pasamos por parámetro en el textArea general.
	*/
	public void escribeGeneral(String txt)
	{
		this.jtAreaOutput.append(txt+"\n");
		Dimension tamanhoTextArea = this.jtAreaOutput.getSize();
		Point p = new Point(
		   0,
		   tamanhoTextArea.height);
		scroll.getViewport().setViewPosition(p);
	}

	/**
	*Escribe el texto que le pasamos por parámetro en el textField de entrada.
	*/
	public void escribeEntrada(String txt)
	{
		this.inputTexto.setText(txt);
	}

	/**
	*Informa de una excepción al usuario en la ventana principal.
	*/
	public void notificaExcepcion(Exception e)
	{
		escribeGeneral("EXCEPCION: "+e.getMessage());
	}

	/**
	*Actualiza la lista de usuarios conectados.
	*/
	public void actualizaUsuarios(LinkedList usuarios)
	{
		Vector<String> users= new Vector<String>();
		for (int i=0;i< usuarios.size();i++)
		{
			Usuario us = (Usuario)usuarios.get(i);
			users.add(us.getNick());
		}
		lista_usuarios.setListData(users.toArray());
	}
}
